package com.enjoyor.soa.traffic.frame.support.redis.impl;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import com.enjoyor.soa.traffic.frame.support.redis.IRedisTool;
import com.enjoyor.soa.traffic.util.base.JSONUtil;

@Service
public class RedisTool implements IRedisTool {

    @Autowired
    private RedisTemplate<String, ?> redisTemplate;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Boolean set(final String key, final String value) {
        boolean result = ((Boolean) this.redisTemplate.execute(new RedisCallback() {
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = RedisTool.this.redisTemplate.getStringSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(value));
                return Boolean.valueOf(true);
            }
        })).booleanValue();
        return Boolean.valueOf(result);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public String get(final String key) {
        String result = (String) this.redisTemplate.execute(new RedisCallback() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = RedisTool.this.redisTemplate.getStringSerializer();
                byte[] value = connection.get(serializer.serialize(key));
                return (String) serializer.deserialize(value);
            }
        });
        return result;
    }

    public boolean expire(String key, long expire) {
        return this.redisTemplate.expire(key, expire, TimeUnit.SECONDS).booleanValue();
    }

    public Object getObject(String key, Class<?> clz) {
        String json = get(key);
        if (json != null) {
            Object object = JSONUtil.toBean(json, clz);
            return object;
        }
        return null;
    }

    public boolean setObject(String key, Object object) {
        String value = JSONUtil.toJson(object);
        return set(key, value).booleanValue();
    }

    public <T> boolean setList(String key, List<T> list) {
        String value = JSONUtil.toJson(list);
        return set(key, value).booleanValue();
    }

    public <T> List<T> getList(String key, Class<T> clz) {
        String json = get(key);
        if (json != null) {
            List<T> list = JSONUtil.toList(json, clz);
            return list;
        }
        return null;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public String lpop(final String key) {
        String result = (String) this.redisTemplate.execute(new RedisCallback() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = RedisTool.this.redisTemplate.getStringSerializer();
                byte[] res = connection.lPop(serializer.serialize(key));
                return (String) serializer.deserialize(res);
            }
        });
        return result;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Boolean del(final String key) {
        Boolean result = ((Boolean) this.redisTemplate.execute(new RedisCallback() {
            @SuppressWarnings("unused")
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = RedisTool.this.redisTemplate.getStringSerializer();
                long res = connection.del(serializer.serialize(key));
                return Boolean.valueOf(true);
            }
        })).booleanValue();
        return Boolean.valueOf(result);
    }
}
